const dateFormatString = (timestamp, type = 0) => {
    const date = new Date(timestamp);

    if (type === 0) {
        return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`.replace(/\b(\w)\b/g, '0$1');
    }

    if (type === 1) {
        return `${date.getFullYear()}-${
            date.getMonth() + 1
        }-${date.getDate()} ${date.getHours()}:${date.getMinutes()}`.replace(/\b(\w)\b/g, '0$1');
    }
};

function numberOnly(value) {
    return value.replace(/\D/g, '');
}

function download(filename, url) {
    const a = document.createElement('a');

    a.download = filename;
    a.href = url;

    document.body.appendChild(a);

    a.click();

    a.remove && a.remove();
}

function compressImage(file, ratio = 0.75) {
    return new Promise((resolve, reject) => {
        const canvas = document.createElement('canvas');
        const context = canvas.getContext('2d');

        const image = new Image();

        image.src = window.URL.createObjectURL(file);
        image.onload = (e) => {
            const { naturalWidth, naturalHeight } = e.target;

            canvas.width = naturalWidth;
            canvas.height = naturalHeight;

            context.drawImage(image, 0, 0);

            if (!HTMLCanvasElement.prototype.toBlob) {
                Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
                    value: function (callback, type, quality) {
                        const dataURL = this.toDataURL(type, quality).split(',')[1];

                        setTimeout(() => {
                            const binStr = atob(dataURL);
                            const len = binStr.length;
                            const arr = new Uint8Array(len);

                            for (let i = 0; i < len; i++) {
                                arr[i] = binStr.charCodeAt(i);
                            }

                            callback(new Blob([arr], { type: type || 'image/png' }));
                        });
                    }
                });
            }

            canvas.toBlob((blob) => resolve(blob), 'image/jpeg', ratio);
        };

        image.onerror = (e) => reject(e);
    });
}

function stringify(data) {
    return Object.keys(data)
        .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`)
        .join('&');
}

function asyncScript(url, isHeader) {
    const script = document.createElement('script');

    script.src = url;

    if (isHeader) {
        document.getElementsByTagName('script')[0].before(script);
    } else {
        [].slice.call(document.getElementsByTagName('script')).pop().after(script);
    }
}

function copy(text, cb) {
    const fakeElement = document.createElement('textarea');

    fakeElement.style.position = 'absolute';
    fakeElement.style.top = '-9999px';
    fakeElement.style.left = '-9999px';

    fakeElement.value = text;

    document.body.appendChild(fakeElement);

    fakeElement.select();

    try {
        document.execCommand('copy');

        cb && cb();
    } catch (e) {
        console.error(e);

        cb && cb(e);
    }

    fakeElement.remove();
}

const cookie = {
    getItem: function (sKey) {
        return (
            decodeURIComponent(
                document.cookie.replace(
                    new RegExp(
                        '(?:(?:^|.*;)\\s*' +
                            encodeURIComponent(sKey).replace(/[-.+*]/g, '\\$&') +
                            '\\s*\\=\\s*([^;]*).*$)|^.*$'
                    ),
                    '$1'
                )
            ) || null
        );
    },
    setItem: function (sKey, sValue, sPath, vEnd, sDomain, bSecure) {
        if (!sKey || /^(?:expires|max-age|path|domain|secure)$/i.test(sKey)) {
            return false;
        }

        let sExpires = '';

        if (vEnd) {
            switch (vEnd.constructor) {
                case Number:
                    sExpires = vEnd === Infinity ? '; expires=Fri, 31 Dec 9999 23:59:59 GMT' : '; max-age=' + vEnd;
                    break;
                case String:
                    sExpires = '; expires=' + vEnd;
                    break;
                case Date:
                    sExpires = '; expires=' + vEnd.toUTCString();
                    break;
            }
        }
        document.cookie =
            encodeURIComponent(sKey) +
            '=' +
            encodeURIComponent(sValue) +
            sExpires +
            (sDomain ? '; domain=' + sDomain : '') +
            (sPath ? '; path=' + sPath : '') +
            (bSecure ? ' secure' : '');

        return true;
    },
    removeItem: function (sKey, sPath, sDomain) {
        if (!sKey || !this.hasItem(sKey)) {
            return false;
        }

        document.cookie =
            encodeURIComponent(sKey) +
            '=; expires=Thu, 01 Jan 1970 00:00:00 GMT' +
            (sDomain ? '; domain=' + sDomain : '') +
            (sPath ? '; path=' + sPath : '');

        return true;
    },
    hasItem: function (sKey) {
        return new RegExp('(?:^|;\\s*)' + encodeURIComponent(sKey).replace(/[-.+*]/g, '\\$&') + '\\s*\\=').test(
            document.cookie
        );
    }
};

function formatTime(timestamp) {
    const currentTime = Date.now();
    const diff = ~~((currentTime - timestamp) / 1000);

    if (diff < 10) {
        return '刚刚';
    }

    if (diff < 60) {
        return `${diff}秒前`;
    }

    if (diff < 60 * 60) {
        return `${~~(diff / 60)}分钟前`;
    }

    if (diff < 60 * 60 * 24) {
        return `${~~(diff / (60 * 60))}小时前`;
    }

    return dateFormatString(timestamp, 0);
}

const deepObj = (target) => {
    if (!(typeof target === 'object' && target !== null)) {
        return target;
    }

    const targ = target instanceof Array ? [] : {};

    for (var key in target) {
        if (Object.hasOwnProperty.call(target, key)) {
            if (typeof target[key] === 'object') {
                targ[key] = deepObj(target[key]);
            } else {
                targ[key] = target[key];
            }
        }
    }

    return targ;
};

const heartbeat = (funcList, delay = 5 * 60 * 1000) => {
    let timer;
    const beat = () => {
        Promise.all(funcList.map((func) => func()))
            .then()
            .finally(() => {
                timer = setTimeout(beat, delay);
            });
    };

    beat();
    return () => clearTimeout(timer);
};

function unique(array) {
    var n = []; //临时数组
    for (var i = 0; i < array.length; i++) {
        if (n.indexOf(array[i]) == -1) n.push(array[i]);
    }
    return n;
}

function getLabelFromDict(dictArray, value) {
    if (!Array.isArray(dictArray)) {
        return '';
    }
    let ele = dictArray.find((item) => item.value === value);
    if (!ele) {
        return '';
    }
    return ele.label;
}

const deleteEmptyStringParams = (paramsObj) => {
    if (typeof paramsObj !== 'object') return paramsObj;

    const copy = JSON.parse(JSON.stringify(paramsObj));
    Object.keys(copy).forEach((key) => {
        if (copy[key] === '') delete copy[key];
    });
    return copy;
};

export {
    dateFormatString,
    numberOnly,
    download,
    compressImage,
    stringify,
    asyncScript,
    copy,
    cookie,
    formatTime,
    deepObj,
    heartbeat,
    unique,
    getLabelFromDict,
    deleteEmptyStringParams
};
